package com.framework.sec.util.filter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import com.framework.bas.bs.IPlmBasBS;
import com.framework.bas.util.SpringUtil;

public class MyInvocationSecurityMetadataSourceService implements
		FilterInvocationSecurityMetadataSource {
	public static final String QUERY_ID = "plm_sec.loadAllPermission";
	public static final String VALUE = "value";
	public static final String RES_NAME = "resName";
	public static final String ROLE_NAME = "roleName";
	
	Map<String, ResRole> resourceMap = new HashMap<String, ResRole>();
	Map<String, ConfigAttribute> configAttributeMap = new HashMap<String, ConfigAttribute>();

	private void loadResourceDefine() {
		IPlmBasBS plmBasBS = SpringUtil.getBean(IPlmBasBS.BEAN_ID,IPlmBasBS.class);
		List<Map<String,String>> queryResults = plmBasBS.query(QUERY_ID,null);
		if(queryResults != null){
			
			for(Map<String, String> resu: queryResults){
				String resValue = resu.get(VALUE);
				if(resValue != null){
					ResRole resRole = resourceMap.get(resValue);
					String roleName = resu.get(ROLE_NAME);
					if(resRole == null){
						resRole = new ResRole(resu.get(RES_NAME), resValue);
						resourceMap.put(resValue,resRole);
						
					}
					ConfigAttribute configAttribute = configAttributeMap.get(roleName);
					if(configAttribute == null){
						configAttribute = new SecurityConfig(roleName);
						configAttributeMap.put(roleName, configAttribute);
					}
					resRole.addConfigAttribute(configAttribute);
				}
			}
		}
    }

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return configAttributeMap.values();
	}

	// 根据URL，找到相关的权限配置。
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		if(resourceMap.size() <= 0){
			loadResourceDefine();
		}
		
		// object 是一个URL，被用户请求的url。
		String url = ((FilterInvocation) object).getRequestUrl();
		int firstQuestionMarkIndex = url.indexOf("?");
		if (firstQuestionMarkIndex != -1) {
			url = url.substring(0, firstQuestionMarkIndex);
		}
		if(resourceMap.get(url) != null){
			return resourceMap.get(url).getConfigAttributes();
		}
		return null;
	}

	@Override
	public boolean supports(Class<?> arg0) {
		return FilterInvocation.class.isAssignableFrom(arg0);
	}
	
	public static class ResRole{
		private String resName;
		private String resValue;
		private List<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
		
		public ResRole(String resName, String resValue) {
			super();
			this.resName = resName;
			this.resValue = resValue;
		}
		public String getResName() {
			return resName;
		}
		public void setResName(String resName) {
			this.resName = resName;
		}
		public String getResValue() {
			return resValue;
		}
		public void setResValue(String resValue) {
			this.resValue = resValue;
		}
		
		public void addConfigAttribute(ConfigAttribute configAttribute){
			configAttributes.add(configAttribute);
		}
		
		public List<ConfigAttribute> getConfigAttributes(){
			return configAttributes;
		}
	}

}
